#include "delaylist.h"
#include "x86.h"
#include "global.h"
#include "proto.h"

void init_delay_node(delay_t* node, PROCESS* proc) {
    node->delay = 0;
    node->lock = 0;
    node->next = NULL;
    node->proc = proc;
}

void init_delaylist(delaylist* dlist, int capacity) {
    dlist->head = NULL;
    dlist->lock = 0;
    dlist->size = 0;
    dlist->capacity = capacity;
}


int insert_delay_node(delaylist* dlist, delay_t* node) {
    if (dlist == NULL || node == NULL) {
        return -1; // 非法输入
    }

    if (dlist->size >= dlist->capacity) {
        return -2; // 延时队列已满
    }

    // while (xchg(&dlist->lock, 1) == 1) {
    //     int myticks = ticks;
    //     while (ticks - myticks < DEFAULT_TICKS) ;
    // }

    // while (xchg(&node->lock, 1) == 1) {
    //     int myticks = ticks;
    //     while (ticks - myticks < DEFAULT_TICKS) ;
    // }
    disable_int();
    

    if (dlist->head == NULL || node->proc->task.delay <= dlist->head->delay) {
        node->delay = node->proc->task.delay;
        dlist->head->delay -= node->delay;
        node->next = dlist->head;
        dlist->head = node;
    } else {
        delay_t* prev = NULL, *cur = dlist->head;
        int delay = cur->delay;
        
        while (cur->next && delay <= node->proc->task.delay) {
            prev = cur;
            cur = cur->next;
            delay += cur->delay;
        }
        
        if (delay <= node->proc->task.delay) { 
            node->delay = node->proc->task.delay - delay;
            cur->next = node;
            node->next = NULL;
        } else {
            node->delay = node->proc->task.delay - delay + cur->delay;
            cur->delay -= node->delay;
            node->next = prev->next;
            prev->next = node;
        }
    }

    dlist->size++;

    xchg(&dlist->lock, 0);
    xchg(&node->lock, 0);

    enable_int();
    return 0; // 插入成功
}


int remove_delay_node(delaylist* dlist, delay_t* node) {
    if (dlist == NULL || node == NULL) {
        return -1; // 非法输入
    }

    // while (xchg(&dlist->lock, 1) == 1) {
    //     int myticks = ticks;
    //     while (ticks - myticks < DEFAULT_TICKS) ;
    // }

    // while (xchg(&node->lock, 1) == 1) {
    //     int myticks = ticks;
    //     while (ticks - myticks < DEFAULT_TICKS) ;
    // }
    disable_int();

    delay_t* prev = NULL, *cur = dlist->head;

    while (cur) {
        if (cur == node) {
            if (prev == NULL) {
                if (cur->next) cur->next->delay += cur->delay;
                dlist->head = cur->next;
            } else {
                if (cur->next) cur->next->delay += cur->delay;
                prev->next = cur->next;
            }
            dlist->size--;
            enable_int();
            return 0; // 移除成功
        }
        prev = cur;
        cur = cur->next;
    }

    enable_int();
    return -2; // 未找到节点，移除失败
}

// 延迟队列整体延迟减 1 tick
void minus_delay(delaylist* dlist) {
    if (dlist == NULL || dlist->head == NULL) return;
    // while (xchg(&dlist->lock, 1) == 1) {
    //     int myticks = ticks;
    //     while (ticks - myticks < DEFAULT_TICKS) ;
    // }

    
    disable_int();
    dlist->head->delay--;
    enable_int();
}


void print_delay_list(delaylist* dlist) {
    if (dlist == NULL) return;

    uart_kprintf("delay list content:\n");
    for (delay_t* cur = dlist->head; cur; cur = cur->next) {
        uart_kprintf("pid: %d; delay: %d\n", cur->proc->task.pid, cur->delay);
    }
    uart_kprintf("\n");
}